package com.yanlight.app.service.impl;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.yanlight.Constants;
import com.yanlight.app.dal.dao.CheckCodeDAO;
import com.yanlight.app.dal.entity.CheckCode;
import com.yanlight.app.service.CheckCodeService;
import com.yanlight.exception.ErrorType;
import com.yanlight.support.http.Response;
import com.yanlight.util.LogUtil;
import com.yanlight.util.MSGUtil;
import com.yanlight.util.ResponseUtil;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
public class CheckCodeServiceImpl implements CheckCodeService {

    @Autowired
    CheckCodeDAO checkCodeDAO;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response save(String phone, String type, String ip) throws ClientException {

        String code = ((int) ((Math.random() * 9 + 1) * 100000)) + "";
        CheckCode checkCode = new CheckCode();

        DateTime now = DateTime.now();
        DateTime useTime = now.plusMinutes(5);

        checkCode.setCode(code);
        checkCode.setPhone(phone);
        checkCode.setType(type);
        checkCode.setIp(ip);
        checkCode.setCreateTime(now.toString(Constants.format1));
        checkCode.setUseTime(useTime.toString(Constants.format1));
        int save = checkCodeDAO.save(checkCode);

        if (save > 0) {
            SendSmsResponse sendSmsResponse = MSGUtil.sendSms(phone, code);
            String responseCode = sendSmsResponse.getCode();
            if (responseCode.equals("OK")) {
                return ResponseUtil.success("验证码发送成功");
            } else {
                return ResponseUtil.fail(ErrorType.CHECK_CODE_SEND_ERROR);
            }
        } else {
            return ResponseUtil.fail(ErrorType.CHECK_CODE_SEND_ERROR);
        }
    }

    @Override
    public boolean canSend(String phone, String type, String ip) {
        int count = checkCodeDAO.countCode(phone, type, ip);
        LogUtil.showLog("count", count);
        if (Constants.messageLimit > count) {
            return true;
        }
        return false;
    }

    @Override
    public ErrorType verifyCode(String phone, String type, String ip) {
        CheckCode newestOne = checkCodeDAO.findNewestOne(phone, type, ip);
        if (newestOne == null) {
            return ErrorType.CHECK_CODE_UNABLE;
        }

        DateTimeFormatter fmt = DateTimeFormat.forPattern(Constants.format1);
        DateTime useTime = fmt.parseDateTime(newestOne.getUseTime());
        DateTime currentTime = DateTime.now();

        long useTimeMillis = useTime.getMillis();
        long currentTimeMillis = currentTime.getMillis();

        if (useTimeMillis < currentTimeMillis) {
            return ErrorType.CHECK_CODE_TIME_OUT;
        }

        int update = checkCodeDAO.updateUsedStatus(newestOne.getId(), true);
        if (update > 0) {
            return ErrorType.SUCCESS;
        } else {
            return ErrorType.SYSTEM_ERROR;
        }
    }
}
